home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 April / macformat-023.iso / Shareware City / Developers / NeoPersist 3.0.8 folder / NeoSource / CNeoStream.cp next >
Encoding:
Text File  |  1994-08-31  |  12.0 KB  |  525 lines  |  [TEXT/MMCC]

  1. /****
  2.  * CNeoStream.cp
  3.  *
  4.  *    C++ implementation for NeoAccess abstract stream class.
  5.  *
  6.  *    Copyright © Neologic Systems 1992-1994. All rights reserved
  7.  *
  8.  ****/
  9.  
  10. #include "NeoTypes.h"
  11. #include CNeoStreamH
  12. #include CNeoBlobH
  13.  
  14. /* ****************************************************************** */
  15.                         /** Instance Methods **/
  16. /* ****************************************************************** */
  17. /*
  18.  * Initialize the stream's mark and length values.
  19.  */
  20. #pragma segment NeoStream
  21. CNeoStream::CNeoStream(void)
  22. {
  23.     fMark = 0;
  24.     fLength = 0;
  25. }
  26.  
  27. /*
  28.  * A virtual destructor is defined just so that its subclass's
  29.  * destructors are also virtual
  30.  */
  31. #pragma segment NeoStream
  32. CNeoStream::~CNeoStream(void)
  33. {
  34. }
  35.  
  36. /* ****************************************************************** */
  37.                         /** Access Methods **/
  38. /* ****************************************************************** */
  39. /*
  40.  * This method needs to be overridden by the environment-specific stream subclasses.
  41.  * Only this subclass knows how to actually close the stream.
  42.  */
  43. #pragma segment NeoClose
  44. void CNeoStream::close(void)
  45. {
  46.     // Null Method
  47. }
  48.  
  49. /*
  50.  * Some types of streams may use some form of data caching mechanism. This
  51.  * method is used to insure that any buffered data committed. 
  52.  */
  53. #pragma segment NeoStream
  54. void CNeoStream::flush(const Boolean aEntireStream)
  55. {
  56.     NeoUsed(aEntireStream);
  57.  
  58.     // Null Method
  59. }
  60.  
  61. /*
  62.  * Some streams may support the concept of a stream creator value. This
  63.  * method is called to obtain the creator value of this stream.
  64.  */
  65. #pragma segment NeoStream
  66. OSType CNeoStream::getCreator(void) const
  67. {
  68.     return 0;
  69. }
  70.  
  71. /*
  72.  * Some streams may need to track the overall length of the data it contains.
  73.  * This method is called to obtain the length of this stream.
  74.  */
  75. #pragma segment NeoStream
  76. long CNeoStream::getLength(void) const
  77. {
  78.     return fLength;
  79. }
  80.  
  81. /*
  82.  * A mark is a location relative to the beginning of a stream's data which
  83.  * is where the next read or write is to occur. This method is called to
  84.  * obtain the stream's mark value.
  85.  */
  86. #pragma segment NeoStream
  87. NeoMark CNeoStream::getMark(void) const
  88. {
  89.     return fMark;
  90. }
  91.  
  92. /*
  93.  * Return the type value for this stream.
  94.  */
  95. #pragma segment NeoStream
  96. OSType CNeoStream::getType(void) const
  97. {
  98.     return 0;
  99. }
  100.  
  101. /*
  102.  * Some siks may support the concept of whether it is open or closed. This
  103.  * method may be called to determine whether the stream has been opened.
  104.  */
  105. #pragma segment NeoStream
  106. Boolean CNeoStream::isOpen(void) const
  107. {
  108.     return TRUE;    // Assume that if the stream exists, then it is open
  109. }
  110.  
  111. /*
  112.  * Some streams may support the concept of a stream creator value. This
  113.  * method is called to set the creator value of this stream.
  114.  */
  115. #pragma segment NeoStream
  116. void CNeoStream::setCreator(const OSType aCreator)
  117. {
  118.     NeoUsed(aCreator);
  119.  
  120.     // Null Method
  121. }
  122.  
  123. /*
  124.  * Some streams may need to track the overall length of the data it contains.
  125.  * This method is called to set the length value of this stream.
  126.  */
  127. #pragma segment NeoStream
  128. void CNeoStream::setLength(const long aLength, const Boolean aReallySet)
  129. {
  130.     NeoUsed(aReallySet);
  131.  
  132.     fLength = aLength;
  133. }
  134.  
  135. /*
  136.  * SetMark sets the position of the mark in the data fork, which
  137.  * specifies the next byte to read or write.
  138.  */
  139. #pragma segment NeoInfo
  140. void CNeoStream::setMark(const NeoMark aMark)
  141. {
  142.     NeoAssert(aMark <= fLength);
  143.     fMark = aMark;
  144. }
  145.  
  146. /*
  147.  * Set the type value for this stream.
  148.  */
  149. #pragma segment NeoStream
  150. void CNeoStream::setType(const OSType aType)
  151. {
  152.     NeoUsed(aType);
  153.  
  154.     NeoAssert(FALSE);
  155. }
  156.  
  157. /* ****************************************************************** */
  158.                         /** Structuring Methods **/
  159. /* ****************************************************************** */
  160. /*
  161.  * Some streams may support the concept of containing a list of items.
  162.  * This method is called to open a list for either reading or writing. 
  163.  */
  164. #pragma segment NeoStream
  165. void CNeoStream::closeList(void)
  166. {
  167.     // Null Method
  168. }
  169.  
  170. /*
  171.  * Some streams may support the concept of containing a list of items.
  172.  * This method is called to close a list after either reading or writing. 
  173.  */
  174. #pragma segment NeoStream
  175. void CNeoStream::openList(const NeoTag aTag)
  176. {
  177.     NeoUsed(aTag);
  178.  
  179.     // Null Method
  180. }
  181.  
  182. /* ****************************************************************** */
  183.                         /** I/O Methods **/
  184. /* ****************************************************************** */
  185. /*
  186.  * Read the specified number of bytes from the stream into the buffer.
  187.  */
  188. #pragma segment NeoStream
  189. void CNeoStream::readBits(void *aBits, const short aCount, const NeoTag aTag)
  190. {
  191.     readChunk(aBits, aCount, aTag);
  192. }
  193.  
  194. /*
  195.  * Position the stream to the given mark then allocate a memory block of the
  196.  * given length then read that number of bytes into the block.
  197.  */
  198. #pragma segment NeoStream
  199. NeoBlob CNeoStream::readBlob(const NeoMark aMark, long &aLength, const NeoTag aTag)
  200. {
  201.     NeoBlob        blob;
  202.     NeoMark        oldMark;
  203.  
  204.     NeoUsed(aTag);
  205.  
  206.     if (aLength) {
  207.         blob = NeoBlobCacheMalloc(aLength);
  208.         NeoFailNil(blob);
  209.         NEOTRY {
  210.             oldMark = getMark();
  211.             setMark(aMark);
  212. #ifdef qNeoMacintosh
  213.             HLock((Handle)blob);
  214. #endif
  215.             readChunk(NeoBlobGetPtr(blob), aLength);
  216. #ifdef qNeoMacintosh
  217.             HUnlock((Handle)blob);
  218. #endif
  219.             setMark(oldMark);
  220.         }
  221.         NEOCATCH {
  222.             NeoBlobCacheFree(blob, aLength);
  223.         }
  224.         NEOENDTRY;
  225.     }
  226.     else {
  227.         blob = nil;
  228.         aLength = 0;
  229.     }
  230.  
  231.     return blob;
  232. }
  233.  
  234. /*
  235.  * Read a single byte of data and treat it as a signed character.
  236.  */
  237. #pragma segment NeoRead
  238. char CNeoStream::readChar(const NeoTag aTag)
  239. {
  240.     char    value;
  241.  
  242.     readChunk(&value, sizeof(value), aTag);
  243.  
  244.     return value;
  245. }
  246.  
  247. /*
  248.  * Read a double floating point value from the stream into the buffer.
  249.  */
  250. #pragma segment NeoStream
  251. NeoDouble CNeoStream::readDouble(const NeoTag aTag)
  252. {
  253.     NeoDouble    value = 0;
  254.  
  255.     readChunk(&value, sizeof(value), aTag);
  256.  
  257.     return value;
  258. }
  259.  
  260. /*                                           
  261.  * Read a floating point value from the stream into the buffer.
  262.  */
  263. #pragma segment NeoStream
  264. NeoFloat CNeoStream::readFloat(const NeoTag aTag)
  265. {
  266.     NeoFloat    value;
  267.  
  268.     readChunk(&value, sizeof(value), aTag);
  269.  
  270.     return value;
  271. }
  272.  
  273. /*
  274.  * Read a long integer from the stream into the buffer.
  275.  */
  276. #pragma segment NeoStream
  277. long CNeoStream::readLong(const NeoTag aTag)
  278. {
  279.     long    value = 0;
  280.  
  281.     readChunk(&value, sizeof(long), aTag);
  282.  
  283.     return value;
  284. }
  285.  
  286. /*
  287.  * Read a long double floating point value from the stream into the buffer.
  288.  */
  289. #pragma segment NeoStream
  290. NeoLongDouble CNeoStream::readLongDouble(const NeoTag aTag)
  291. {
  292.     NeoLongDouble    value = 0;
  293.  
  294.     readChunk(&value, sizeof(value), aTag);
  295.  
  296.     return value;
  297. }
  298.  
  299. /*
  300.  * Read a byte from the stream and return Boolean indicating whether that byte is 0.
  301.  */
  302. #pragma segment NeoStream
  303. Boolean CNeoStream::readBoolean(const NeoTag aTag)
  304. {
  305.     char    buffer;
  306.     
  307.     readChunk(&buffer, 1, aTag);
  308.     return (Boolean)(buffer != 0);
  309. }
  310.  
  311. /*
  312.  * Read a native string from the stream into the buffer. The universal format
  313.  * of native strings is a one byte length followed by up to 255 characters
  314.  * of the string.
  315.  */
  316. #pragma segment NeoStream
  317. void CNeoStream::readNativeString(CNeoString &aString, const long aMaxLength, const NeoTag aTag)
  318. {
  319.     aString[0] = 0;
  320. #ifdef qNeoMacintosh
  321.     readChunk((unsigned char *)aString, (aMaxLength ? aMaxLength : 255), aTag);
  322. #else
  323.     char    buffer[256];
  324.  
  325.     NeoAssert(aMaxLength <= 255);
  326.     readChunk(buffer, (aMaxLength ? aMaxLength : 255), aTag);   
  327.     NeoAssert(buffer[0] < aMaxLength);
  328.     NeoBlockMove(buffer+1, aString, buffer[0]);
  329.     ((char *)aString)[buffer[0]] = 0;
  330. #endif
  331. }
  332.  
  333. /*
  334.  * The process of reading an object from a stream sometimes needs to begin
  335.  * by first configuring or otherwise preparing the stream. The readObject
  336.  * method is overridden by those streams to perform these preamble tasks.
  337.  */
  338. #pragma segment NeoStream
  339. void CNeoStream::readObject(CNeoPersist *aObject, const NeoTag aTag)
  340. {
  341.     NeoUsed(aObject);
  342.     NeoUsed(aTag);
  343.  
  344.     // Null Method
  345. }
  346.  
  347. /*
  348.  * Read a short integer from the stream into the buffer.
  349.  */
  350. #pragma segment NeoStream
  351. short CNeoStream::readShort(const NeoTag aTag)
  352. {
  353.     short    value    = 0;
  354.  
  355.     readChunk(&value, sizeof(short), aTag);
  356.  
  357.     return value;
  358. }
  359.  
  360. /*
  361.  * Application specific clients of a stream can sometimes store and retrieve a
  362.  * variable length, null terminated string in a stream. This method assumes
  363.  * that the last character read is a terminating null.
  364.  */
  365. #pragma segment NeoStream
  366. void CNeoStream::readString(void *aBuffer, const long aLength, const NeoTag aTag)
  367. {
  368.     ((char *)aBuffer)[0] = 0;
  369.     readChunk(aBuffer, aLength, aTag);
  370. }
  371.  
  372. /*
  373.  * Write the specified number of bytes from the buffer to the stream.
  374.  */
  375. #pragma segment NeoStream
  376. void CNeoStream::writeBits(const void *aBits, const short aCount, const NeoTag aTag)
  377. {
  378.     writeChunk(aBits, aCount, aTag);
  379. }
  380.  
  381. /*
  382.  * Position the stream to the given mark then write that number of
  383.  * bytes to the stream.
  384.  */
  385. #pragma segment NeoStream
  386. void CNeoStream::writeBlob(NeoBlob aBlob, const NeoMark aMark, const long aLength, const NeoTag aTag)
  387. {
  388.     NeoMark        oldMark;
  389.  
  390.     if (aBlob) {
  391.         oldMark = getMark();
  392.         setMark(aMark);
  393. #ifdef qNeoMacintosh
  394.         HLock((Handle)aBlob);
  395. #endif
  396.         writeChunk(NeoBlobGetPtr(aBlob), aLength, aTag);
  397. #ifdef qNeoMacintosh
  398.         HUnlock((Handle)aBlob);
  399. #endif
  400.         setMark(oldMark);
  401.     }
  402. }
  403.  
  404. /*
  405.  * Write a 0 byte to the stream if aBool == FALSE.
  406.  * Write a non-0 byte to the stream otherwise.
  407.  */
  408. #pragma segment NeoStream
  409. void CNeoStream::writeBoolean(const Boolean aBool, const NeoTag aTag)
  410. {                  
  411.     unsigned char     buffer;
  412.     
  413.     if (aBool)
  414.         buffer = 0xFF;
  415.     else
  416.         buffer = 0;
  417.     writeChunk(&buffer, 1, aTag);
  418. }
  419.  
  420. /*
  421.  * Write a single byte of data and treat it as a signed character.
  422.  */
  423. #pragma segment NeoRead
  424. void CNeoStream::writeChar(const char aValue, const NeoTag aTag)
  425. {
  426.     writeChunk(&aValue, sizeof(aValue), aTag);
  427. }
  428.  
  429. /*
  430.  * Write a double floating point value to the stream.
  431.  */
  432. #pragma segment NeoStream
  433. void CNeoStream::writeDouble(const NeoDouble &aValue, const NeoTag aTag)
  434. {
  435.     writeChunk(&aValue, sizeof(aValue), aTag);
  436. }
  437.  
  438. /*                               
  439.  * Write a floating point value to the stream.
  440.  */
  441. #pragma segment NeoStream
  442. void CNeoStream::writeFloat(const NeoFloat &aValue, const NeoTag aTag)
  443. {
  444.     writeChunk(&aValue, sizeof(aValue), aTag);
  445. }
  446.  
  447. /*
  448.  * Write a long integer to the stream.
  449.  */
  450. #pragma segment NeoStream
  451. void CNeoStream::writeLong(const long aValue, const NeoTag aTag)
  452. {
  453.     writeChunk((const void *)&aValue, sizeof(long), aTag);
  454. }
  455.  
  456. /*
  457.  * Write a long double floating point value to the stream.
  458.  */
  459. #pragma segment NeoStream
  460. void CNeoStream::writeLongDouble(const NeoLongDouble &aValue, const NeoTag aTag)
  461. {
  462.     writeChunk(&aValue, sizeof(aValue), aTag);
  463. }
  464.  
  465. /*
  466.  * Write a native string to the stream. The universal format of native
  467.  * strings is a one byte length followed by up to 255 characters of the
  468.  * string.
  469.  */
  470. #pragma segment NeoStream
  471. void CNeoStream::writeNativeString(const CNeoString &aString, const long aMaxLength, const NeoTag aTag)
  472. {
  473. #ifdef qNeoMacintosh
  474.     writeChunk((unsigned char *)aString, aMaxLength, aTag);
  475. #else
  476.     char            buffer[256];
  477.  
  478.     buffer[0] = aString.getLength();
  479.                                          
  480.     NeoAssert(aMaxLength <= 255);
  481.     if (buffer[0] > aMaxLength -1)
  482.         buffer[0] = aMaxLength -1;
  483.     NeoBlockMove(aString, buffer+1, buffer[0]);
  484.     writeChunk(buffer, aMaxLength, aTag);
  485. #endif
  486. }
  487.  
  488. /*
  489.  * The process of writing an object to a stream sometimes involves first
  490.  * configuring or otherwise preparing the stream. The writeObject method
  491.  * overridden by those streams to perform these preamble tasks.
  492.  */
  493. #pragma segment NeoStream
  494. void CNeoStream::writeObject(CNeoPersist *aObject, const NeoTag aTag)
  495. {
  496.     NeoUsed(aObject);
  497.     NeoUsed(aTag);
  498.  
  499.     // Null Method
  500. }
  501.  
  502. /*
  503.  * Write a short integer to the stream.
  504.  */
  505. #pragma segment NeoStream
  506. void CNeoStream::writeShort(const short aValue, const NeoTag aTag)
  507. {
  508.     writeChunk((const void *)&aValue, sizeof(short), aTag);
  509. }
  510.  
  511. /*
  512.  * Application specific clients of a stream can sometimes store and retrieve a
  513.  * variable length, null terminated string in a stream. This method assumes
  514.  * that the last character read is a terminating null.
  515.  *
  516.  * Note: I know I'm writing out aMaxLength bytes when the string may in
  517.  * fact be shorter. It has to be that way, believe me!
  518.  */
  519. #pragma segment NeoStream
  520. void CNeoStream::writeString(const void *aString, const long aMaxLength, const NeoTag aTag)
  521. {
  522.     writeChunk(aString, aMaxLength, aTag);
  523. }
  524.  
  525.